/*

PhyML:  a program that  computes maximum likelihood phylogenies from
DNA or AA homologous sequences.

Copyright (C) Stephane Guindon. Oct 2003 onward.

All parts of the source except where indicated are distributed under
the GNU public licence. See http://www.opensource.org for details.

*/

#ifndef RATES_H
#define RATES_H

void RATES_Monte_Carlo_Mean_Rates(arbre *tree);
void RATES_Monte_Carlo_Mean_Rates_Pre(node *a, node *d, edge *b, double curr_rate, arbre *tree);
void RATES_Print_Rates(arbre *tree);
void RATES_Print_Rates_Pre(node *a, node *d, edge *b, arbre *tree);
trate *RATES_Make_Rate_Struct(int n_otu);
void RATES_Init_Rate_Struct(trate *rates, int n_otu);
void RATES_Classify_Branches(arbre *tree);
void RATES_Adjust_Rates(arbre *tree);
void RATES_Adjust_Rates_Local_Pre(node *a, node *d, edge *b, arbre *tree);
void RATES_Adjust_Rates_Local(node *a, node *d, edge *b1, arbre *tree);
void RATES_Record_T(arbre *tree);
void RATES_Restore_T(arbre *tree);
void RATES_Monte_Carlo_Mean_Rates_Core(double t_lim_sup, double t_lim_inf, double *curr_rate, double *mean_rate, double lexp, double alpha);
double RATES_Lk_Rates(arbre *tree);
void RATES_Lk_Rates_Pre(node *a, node *d, edge *b, arbre *tree);
void RATES_Fill_Node_Rates_Pre(node *a, node *d, edge *b, double *node_r, arbre *tree);
void RATES_Fill_Node_Rates(double *node_r, arbre *tree);
void RATES_Optimize_Node_Times_Serie_Fixed_Br_Len(node *a, node *d, arbre *tree);
void RATES_Optimize_Lexp(arbre *tree);
void RATES_Round_Optimize(arbre *tree);
void RATES_Optimize_Lexp(arbre *tree);
void RATES_Optimize_Alpha(arbre *tree);
double RATES_Dmu(double mu, int n_jumps, double dt, double a, double b, double lexp, int min_n, int jps_dens);
double RATES_Dr_X_Dx(double r, double mu, double y, double dt, double a, double b, double lexp);
double RATES_Dmu_Given_Y_Trpzd(double mu, double y, double dt, double a, double b, double lexp, 
			       int nsteps, double beg, double end, double prevs);
double RATES_Dmu_Given_Y_Std(double mu, double y, double dt, double a, double b, double lexp);
double RATES_Dmu_Given_Y_Romb(double mu, double y, double dt, double a, double b, double lexp);
double RATES_Dmu_Given_Y(double mu, double y, double dt, double a, double b, double lexp);
double RATES_Dy_Given_Mu(double mu, double y, double dt, double a, double b, double lexp);
double RATES_Dmu2_Given_Y_X_Dy_Given_Mu1(double mu1, double mu2, double y, double dt1, double dt2, double a, double b, double lexp);
double RATES_Dmu2_Given_Mu1_Trpz(double mu1, double mu2, double dt1, double dt2, double a, double b, double lexp,
				 int nsteps, double beg, double end, double prevs);
double RATES_Dmu2_And_Mu1(double mu1, double mu2, double dt1, double dt2, double a, double b, double lexp);
double RATES_Dmu2_Given_Mu1(double mu1, double mu2, double dt1, double dt2, double a, double b, double lexp);
double RATES_Dmu2_Given_Mu1_Romb(double mu1, double mu2, double dt1, double dt2, double a, double b, double lexp);
void RATES_Random_Branch_Lengths(arbre *tree);
void RATES_Bracket_N_Jumps(int *up, int *down, double param);
void RATES_Set_Node_Times(arbre *tree);
void RATES_Set_Node_Times_Pre(node *a, node *d, arbre *tree);
void RATES_Randomize_Node_Times(arbre *tree);
void RATES_Randomize_Node_Times_Pre(node *a, node *d, arbre *tree);
void RATES_Optimize_Node_Times(arbre *tree);
double RATES_Exp_Y(double mu1, double mu2, double dt1, double lexp);
double RATES_Dmu2_Given_Mu1_Bis(double mu1, double mu2, double dt1, double dt2, double alpha, double beta, double lexp);
void RATES_Replace_Br_Lengths_By_Rates_Pre(node *a, node *d, edge *b, arbre *tree);
void RATES_Replace_Br_Lengths_By_Rates(arbre *tree);

void RATES_Get_Mean_Rates(arbre *tree);
void RATES_Get_Mean_Rates_Pre(node *a, node *d, edge *b, double *r_a, double alpha, double lexp, arbre *tree);
void RATES_Expect_Number_Subst(double t_beg, double t_end, double *r_beg, double alpha, double lexp, int *n_jumps, double *mean_r);
void RATES_Optimize_Clock_Rate(arbre *tree);
double RATES_Dmu1_Given_Lbda_And_Mu2(double lbda, double mu1, double mu2, double alpha, double beta);
double RATES_Dmu1_And_Mu2_One_Jump_Trpz(double mu1, double mu2, double a, double b,
					  int nsteps, double beg, double end, double prevs);
double RATES_Dmu1_And_Mu2_One_Jump_One_Interval(double mu1, double mu2, double a, double b);
double RATES_Dmu1_And_Mu2_One_Jump_Two_Intervals(double dt1, double dt2, double mu1, double mu2, double a, double b);

double RATES_Dmu1_And_Mu2_One_Jump_Old(double mu1, double mu2, double a, double b);

double RATES_Dmu2_And_Min_N_Given_Mu1(double mu1, double mu2, double dt1, double dt2, int n_min, double a, double b, double lexp);
double RATES_Dmu2_And_Mu1_Given_N(double mu1, double mu2, double dt1, double dt2, int n, double a, double b, double lexp);
double RATES_Lk_Rates_Core(double mu1, double mu2, int n1, int n2, double dt1, double dt2, arbre *tree);
void RATES_Init_Triplets(arbre *tree);
double RATES_Lk_Change_One_Time(node *n, double new_t, arbre *tree);
void RATES_Update_Triplet(node *n, arbre *tree);
void RATES_Print_Triplets(arbre *tree);
double RATES_Lk_Change_One_Rate(node *d, double new_rate, arbre *tree);
double RATES_Dmu2_And_Mu1_Given_Min_N(double mu1, double mu2, double dt1, double dt2, int n_min, double a, double b, double lexp);
double RATES_Dmu2_And_Mu1_Given_N_Normal(double mu1, double mu2, double dt1, double dt2, int n, double a, double b, double lexp);
double RATES_Coeff_Corr(double alpha, double beta, int n1, int n2);
double RATES_Dmu2_And_Mu1_Given_N_Full(double mu1, double mu2, double dt1, double dt2, int n, double a, double b, double lexp);
double RATES_Dmu1_Given_V_And_N(double mu1, double v, int n, double dt1, double a, double b);
double RATES_Yule(arbre *tree);
double RATES_Check_Mean_Rates(arbre *tree);
void RATES_Check_Mean_Rates_Pre(node *a, node *d, edge *b, double *sum, arbre *tree);
void RATES_Adjust_Clock_Rate(arbre *tree);
void RATES_Discretize_Rates(arbre *tree);
void RATES_Discretize_Rates_Pre(node *a, node *d, edge *b, arbre *tree);
double RATES_Dmu_Given_V_And_MinN(double mu, double dt, double v, int minn, double a, double b, double lexp);
double RATES_Dmu_One(double mu, double dt, double a, double b, double lexp);
double RATES_Compound_Core(double mu1, double mu2, int n1, int n2, double dt1, double dt2, double alpha, double beta, double lexp, double eps, int approx);
void RATES_Record_Rates(arbre *tree);
void RATES_Reset_Rates(arbre *tree);
void RATES_Record_Times(arbre *tree);
void RATES_Reset_Times(arbre *tree);
void RATES_Update_T_Rates_Pre(node *a, node *d, arbre *tree);
void RATES_Update_T_Rates(arbre *tree);
void RATES_Get_Br_Len(arbre *tree);
void RATES_Get_Rates_From_Bl(arbre *tree);
double RATES_Compound_Core_Joint(double mu1, double mu2, int n1, int n2, double dt1, double dt2, 
				 double alpha, double beta, double lexp, double eps, int approx);
double RATES_Dmu_Joint(double mu, int n, double dt, double a, double b, double lexp, int min_n);
double RATES_Compound_Core_Marginal(double mu1, double mu2, double dt1, double dt2, double alpha, 
				    double beta, double lexp, double eps, int approx);
double RATES_Lk_Jumps(arbre *tree);
void RATES_Set_Rates_Prior_Mean(arbre *tree);
void RATES_Set_Rates_Prior_Mean_Pre(node *a, node *d, arbre *tree);
void RATES_Set_Rates_Post_Mean_And_Cov(arbre *tree);

#endif
